#include <stdlib.h>
#include "ListaAlumno.h"
#include "Alumno.h"

ListaAlumno* crear_ListaAlumno(){
    ListaAlumno* lista= malloc(sizeof(ListaAlumno));
    lista->cant=0;
    lista->fin=NULL;
    lista->fin_arch=NULL;
    lista->ini=NULL;
    return lista;
}

ListaAlumno nueva_ListaAlumno(){
    ListaAlumno lista;
    lista.cant=0;
    lista.fin=NULL;
    lista.fin_arch=NULL;
    lista.ini=NULL;
    return lista;
}

void insertarFinal_ListaAlumno(ListaAlumno* lista, Alumno* alumno){
    NodoListaAlumno* nuevo = malloc(sizeof(NodoListaAlumno));
    nuevo->alumno=alumno;
    nuevo->ant=lista->fin;
    nuevo->sig=NULL;
    if(lista->cant == 0){
        lista->ini=nuevo;
    } else{
        lista->fin->sig=nuevo;
    }
    lista->fin=nuevo;
    (lista->cant)+=1;
}

void imprimir_ListaAlumno(ListaAlumno* L){
    NodoListaAlumno* i;
    for (i = L->ini; i != NULL; i = i->sig){
        imprimir_Alumno(i->alumno);
    }
}

void imprimir_ListaAlumno_des(ListaAlumno* L){
    NodoListaAlumno* i;
    for (i = L->fin; i != NULL; i = i->ant){
        imprimir_Alumno(i->alumno);
    }
}


NodoListaAlumno* rem_ini_ListaAlumno(ListaAlumno *L){
    NodoListaAlumno *aux;
    aux = L->ini;
    if(L->cant<=1){
        L->ini=NULL;
        L->fin=NULL;
    }else{
        L->ini=L->ini->sig;
    }
    (L->cant)--;
    return aux;
}

void separar_ListaAlumno(ListaAlumno *L, ListaAlumno *l, ListaAlumno *r){
    int i;
    NodoListaAlumno *aux;
    Alumno *a;
    int num=(L->cant)/2;
    int num1 = L->cant;
    for(i=0;i<num;i++){
        aux = rem_ini_ListaAlumno(L);
        a = aux->alumno;
        insertarFinal_ListaAlumno(l,a);
    }
    for(i=num;i<num1;i++){
        aux = rem_ini_ListaAlumno(L);
        a = aux->alumno;
        insertarFinal_ListaAlumno(r,a);
    }
    
}

int comp_ListaAlumno(ListaAlumno *l,ListaAlumno *r,int campo){
    if(campo == 0){
        if((l->ini->alumno->codigo)<=(r->ini->alumno->codigo)) return 1;
        return 0;
    }else if(campo == 1){
        if(strcmp(l->ini->alumno->nombre,r->ini->alumno->nombre)==-1) return 1;
        return 0;
    }else if(campo == 2){
        if((l->ini->alumno->espec)<=(r->ini->alumno->espec))return 1;
        return 0;
    }else if(campo == 3){
        if((valor_Fecha(l->ini->alumno->fecha_nac)<=valor_Fecha(r->ini->alumno->fecha_nac)))return 1;
        return 0;
    }
}

void merge_ListaAlumno(ListaAlumno *L,ListaAlumno *l,ListaAlumno *r,int campo){
    NodoListaAlumno *aux;
    Alumno *a;
    
    while(l->cant>0 || r->cant>0){
        if(l->cant>0 && r->cant>0){
            if(comp_ListaAlumno(l,r,campo)){
                aux = rem_ini_ListaAlumno(l);
                a = aux->alumno;
                insertarFinal_ListaAlumno(L,a);
            }else{
                aux = rem_ini_ListaAlumno(r);
                a = aux->alumno;
                insertarFinal_ListaAlumno(L,a);
            }
        }else if(l->cant>0){
            aux = rem_ini_ListaAlumno(l);
                a = aux->alumno;
                insertarFinal_ListaAlumno(L,a);
        }else if(r->cant>0){
            aux = rem_ini_ListaAlumno(r);
                a = aux->alumno;
                insertarFinal_ListaAlumno(L,a);
        }
    }
}

void merge_sort_ListaAlumno(ListaAlumno *L, int campo){
    if(L->cant<=1)return;
    ListaAlumno l,r;
    l=nueva_ListaAlumno();
    r=nueva_ListaAlumno();
    separar_ListaAlumno(L,&l,&r);
    merge_sort_ListaAlumno(&l,campo);
    merge_sort_ListaAlumno(&r,campo);
    merge_ListaFiesta(L,&l,&r,campo);
}
